import numpy as np
import matplotlib.pyplot as plt
import wave
import struct
import os
import re

import notations.happy_birthday as notation

BASE = 1760  # base frequency, the central C is at 440Hz
DTYPE = np.int16  # relative to the samplewidth, for future compatibility
SAMPLE_RATE = 44100
SAMPLE_WIDTH = 2
LEN = int(SAMPLE_RATE * 0.5)  # length of a pat, in time
SP = ' '

# ===== ===== ===== =====
# Load sounds of tone
# ===== ===== ===== =====
# 1 = base, -11 = falling of base, 11 = rising of base
# ie. when 1 = C, then -11 = falling C, 11 = rising C 
sounds = {}
for i in range(-2, 3):
    path = str(int(BASE * 2**i))
    for j in range(1, 8):
        w = wave.open(os.path.join(path, '%i.wav' % j), 'rb')
        w_data = w.readframes(w.getnframes())
        w_data = np.fromstring(w_data, dtype=DTYPE)
        if i == 0:
            idx = '%i' % j
        else:
            idx = '%i%i' % (i, j)
        sounds[idx] = w_data


# ===== ===== ===== =====
# Generate the song
# ===== ===== ===== =====
def write_song(nota, durt):
    nota = re.split('[ ]+', nota)
    durt = re.split('[ ]+', durt)
    if len(nota) != len(durt):
        raise Exception('len of nota != len of durt %i,%i' % (len(nota), len(durt)))

    w = wave.open('output.wav', 'wb')
    w.setnchannels(1)
    w.setsampwidth(SAMPLE_WIDTH)
    w.setframerate(SAMPLE_RATE)
    for i in range(len(nota)):
        if nota[i] == '':
            continue
        
        print('nota: ', repr(nota[i]), 'durt:', repr(durt[i]))
        pat = float(durt[i])
        nframes = int(pat * LEN)
        frames = sounds[nota[i]][:nframes]
        w.writeframesraw(frames)
    w.writeframes(b"")
    w.close()


write_song(notation.tones, notation.durt)
print("All done.")
# plt.plot(tones[-11][:300])
# plt.show()
